﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;

namespace SimpleIR
{
	/// <summary>
	/// Represents a root identifier (a local variable, fixed parameter, or a static field).
	/// </summary>
	public abstract class IRRoot : IRCompareableName
	{
		protected IRRoot()
			: base()
		{ ;}
	}

	/// <summary>
	/// Represents a single variable name.
	/// </summary>
	public sealed class IRVarName : IRRoot
	{
		/// <summary>
		/// The string name of the variable.
		/// </summary>
		public readonly string VarName;

		internal IRVarName(string name)
			: base()
		{ this.VarName = name; }

		public override string ToString()
		{ return this.VarName; }
	}

	/// <summary>
	/// Represents a single static field.
	/// </summary>
	public sealed class IRStaticField : IRRoot 
	{
		/// <summary>
		/// The field qualifier tag for this field.
		/// </summary>
		public readonly FieldQualifiers FieldQualifier;

		/// <summary>
		/// Class type where this field is defined.
		/// </summary>
		public readonly IRType DefinedInClass;

		/// <summary>
		/// Return the name of this field.
		/// </summary>
		public readonly string FieldName;

		/// <summary>
		/// Type that is stored in this field.
		/// </summary>
		public readonly IRType FieldType;

		internal IRStaticField(FieldQualifiers fq, IRType defClass, string name, IRType fieldType)
			: base()
		{
			this.FieldQualifier = fq;
			this.DefinedInClass = defClass;
			this.FieldName = name;
			this.FieldType = fieldType;
		}

		public override string ToString()
		{ return this.DefinedInClass.ToString() + "." + this.FieldName; }
	}

	/// <summary>
	/// Represents a fixed parameter alias name.
	/// Not used at runtime but useful in the static analysis to ensure a fixed point of reference for the pointer parameters to a method.
	/// </summary>
	public sealed class IRFixedParameter : IRRoot
	{
		/// <summary>
		/// The name of this fixed parameter.
		/// </summary>
		public readonly string FixedParamName;

		/// <summary>
		/// The name of the parameter variable that this is aliased with at method entry.
		/// </summary>
		public readonly string ForParam;

		internal IRFixedParameter(string fixedname, string paramname)
			: base()
		{
			this.FixedParamName = fixedname;
			this.ForParam = paramname;
		}
	}
}
